package com.fintech.pangu.upms.synchro.controller;

import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
import com.google.common.collect.Multimaps;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationListener;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.async.DeferredResult;

import java.util.Collection;

@Slf4j
@RestController
public class UPMSNotificationController implements ApplicationListener<UPMSReleaseEvent> {

    private static final long TIMEOUT = 60 * 1000;//60 seconds

    private static final ResponseEntity<String>
            NOT_MODIFIED_RESPONSE = new ResponseEntity<>("NOT_MODIFIED", HttpStatus.NOT_MODIFIED);


    private Multimap<String, DeferredResult<ResponseEntity<String>>> watchRequests = Multimaps.synchronizedSetMultimap(HashMultimap.create());


    @RequestMapping("/watch/{appName}")
    public DeferredResult<ResponseEntity<String>> watch(@PathVariable("appName") String appName){
        log.info("Request received");
        DeferredResult<ResponseEntity<String>> deferredResult = new DeferredResult<ResponseEntity<String>>(TIMEOUT, NOT_MODIFIED_RESPONSE);
        //DeferredResult<ResponseEntity<String>> deferredResult = new DeferredResult<ResponseEntity<String>>();
        //当deferredResult完成时（不论是超时还是异常还是正常完成），移除watchRequests中相应的watch key
        deferredResult.onCompletion(new Runnable() {
            @Override
            public void run() {
                log.info("remove key:" + appName);
                watchRequests.remove(appName, deferredResult);
            }
        });
        watchRequests.put(appName, deferredResult);
        log.info("Servlet thread released");
        return deferredResult;
    }





    @Override
    public void onApplicationEvent(UPMSReleaseEvent event) {
        String appName = (String)event.getSource();
        log.info("Listen UPMSReleaseEvent about: " + appName);
        if (watchRequests.containsKey(appName)) {
            Collection<DeferredResult<ResponseEntity<String>>> deferredResults = watchRequests.get(appName);
            Long time = System.currentTimeMillis();
            // TODO
            // 注意：只通知一个客户端做缓存刷新即可，因为共用Redis，不用每个都通知 或者 每个都通知但只有一个更新Redis
            for (DeferredResult<ResponseEntity<String>> deferredResult : deferredResults) {
                ResponseEntity<String> responseEntity = new ResponseEntity<String>(appName + " changed:" + time, HttpStatus.OK);
                log.info("deferredResult.setResult()：" + responseEntity);
                deferredResult.setResult(responseEntity);
            }
        }
    }
}
